#pragma once

#include <ft2build.h>
#include FT_FREETYPE_H

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>

#include "BltInfo.h"
#include "Font.h"
#include "Window.h"
#include "Graphic2D.h"

using namespace Graphics;

namespace Graphics
{
	class GraphicFactory;
}

namespace OGLs
{
	class GraphicOGL:public Graphic2D
	{
		friend class GraphicFactoryOGL;

		// freetype support
		FT_Library		m_FT_library;
		FT_Face			m_FT_face;
		Font			m_Font;
		int				m_FontHeight;

		WinApp::Window&		m_Win;
		HGLRC				m_RC;
		//IOGLXSprite*		m_pSprite;
		//LPDIRECT3DSURFACE9	m_pBackBuffer;
		//LPDIRECT3DTEXTURE9	m_pOGLTexture;
		//LPDIRECT3DDEVICE9	m_pOGLDevice;
		//LPDIRECT3DTEXTURE9	m_pTempBuffer;

		//// vertex buffer
		//IDirect3DVertexBuffer9*	m_pVB;
		//
		//// pointer of vertex buffer
		//RTG_VERTEX*				m_pVertex;
		//
		//// index buffer for render quad
		//IDirect3DIndexBuffer9*	m_pIB;
		
		//// vertex array for render quad
		//RTG_VERTEX		m_Quad[4];
		
		//// quad count of vertex buffer
		//int m_PrimCount;

		//// graphic state
		//LPDIRECT3DTEXTURE9		m_pLastTexture;
		//LPDIRECT3DSURFACE9		m_pLastTarget;
		//bool					m_IsBegin;
		//bool					m_IsUpdate;
		//bool					m_IsDiffuseOnly;
		//BLEND_TYPE				m_LastBlendType;
		
		bool Init();
		explicit GraphicOGL(WinApp::Window& win);

	public:
		//// Set the font type
		//bool SetFont(const Font& font);

		//// render text to the render target
		//bool RenderText(const std::wstring& text, const Rect& destRect);

		// draw text in the target rect
		virtual bool TextDraw(const std::wstring& text,
							  const Font& font,
							  const Rect& destRect);

		// draw a 2D rect to the target
		virtual bool Blt(Drawable* pSrc,
						 const Rect* pSrcRect, 
						 const Rect* pDestRect,
						 const BltInfo* pBltInfo);
		
		// clear the screen
		virtual bool Clear(Rect* const pRect=0, DWORD color=0);

		// be called by clocksource
		void OnClock(SourceType& t);

		//// transform the target
		//bool Transform2D(	float ox,float oy,				// translation
		//					float cx,float cy,float angle,	// rotation
		//					float scaleX,float scaleY);		// scale

		//// rotate the target
		//bool Transform3D(	float ox,float oy,float oz,	// translation
		//					float cx,float cy,float cz,	// rotation
		//					float rx,float ry,float rz,float angle,
		//					float scaleX,float scaleY,float scaleZ);	// scale

		//// change render target
		//bool SetRenderTarget(LPDIRECT3DSURFACE9	pSurface);

		//// render a quad
		//bool RenderQuad(	LPDIRECT3DTEXTURE9 pTexture,
		//					const Rect& srcRect,
		//					const Rect& destRect,
		//					const BltInfo* pBltInfo);
		//bool RenderQuad(	LPDIRECT3DTEXTURE9 pTexture,
		//					RTG_VERTEX* pVertex);

		//// update the vertex buffer to target
		//bool Update(bool isEnd = false);

		//// called before renderquad
		//bool Begin(void);

		//// called after renderquad
		//bool End(void);

		//// refresh the screen
		//bool Present(void);

		//// clear the surface
		//bool ClearSurface(	LPDIRECT3DSURFACE9 const pSurface, 
		//					Rect* const pRect=0,
		//					DWORD color=0);

		virtual bool BindTexture(void);

		//bool BindTextureOGL( LPDIRECT3DTEXTURE9 pTexture);

		virtual	int					GetWidth(void);
		virtual	int					GetHeight(void);
		//LPDIRECT3DDEVICE9			GetDevice(void);
		//IOGLXSprite*				GetSprite(void);

	private:
		~GraphicOGL(void);
	};
}